﻿using System;
using System.Linq.Expressions;
using System.Web.Mvc;

namespace Entropy.Ext
{
    public static class HtmlHelperExtensions
    {
        public static void PublishName(this WebViewPage webViewPage, Expression<Func<IBase>> component)
        {
            var lambda = (LambdaExpression)component;
            var node = lambda.Body;
            var intf = lambda.Compile().DynamicInvoke();
            var factoryObj = ((IInterfacedFactoryAccess)intf).Access();
            var intfFactory = factoryObj as InterfacedFactory;
            if (intfFactory != null)
            {
                var syntaxTree = (ISyntaxTree)webViewPage.Context.Items["EntropySyntaxTree"];
                var expr = syntaxTree.InterfaceFactories[intfFactory];
                var ctor = (AstConstructor)expr;
                ctor.PronouncedName = ((MemberExpression)node).Member.Name;
            }
        }

        public static IExtFactory Ext(this WebViewPage webViewPage, FormatterKind formatter = FormatterKind.Debug)
        {

            var result = webViewPage.Context.Items["EntropyHolder"] as IExtFactory;
            if (result == null)
            {
                var fmt = FormatterFactory(formatter);
                ISyntaxTree syntaxTree = new SyntaxTree();
                webViewPage.Context.Items["EntropySyntaxTree"] = syntaxTree;
                IAsgBuilder asg = new AsgBuilder(new ExtAccent(), new SequentialTypeNaming());
                result = ExtFactoryProxy.Create(webViewPage, syntaxTree, () => fmt.Format(asg.Compile(syntaxTree.Result())));


                webViewPage.Context.Items["EntropyHolder"] = result;
            }
            return result;
        }

        private static IJsFormatter FormatterFactory(FormatterKind formatter)
        {
            DebugFormatter debugFormatter;
            switch (formatter)
            {
                case FormatterKind.Debug:
                    debugFormatter = new DebugFormatter();
                    break;
                default:
                    throw new Exception("unimlemented formatter");
            }
            return debugFormatter;
        }
    }

    public enum FormatterKind
    {
        Debug,
        Minified,
        Obfuscate
    }
}